package energy_conf

import (
	"context"
	"fmt"

	gpb "gitee.com/cloudapex/protos/crm_base/pb"
	gpa "gitee.com/cloudapex/protos/hr_cache/pb"

	crm_base "service/model/crm_base"
	mCache "service/model/hr_cache"
	"strings"

	"gitee.com/cloudapex/ulern/htp"
	"gitee.com/cloudapex/ulern/util"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
	"github.com/gin-gonic/gin"

	"service/model/mod"
	"strconv"
	"time"
)

/*
 * 描述:职能配置信息列表
 * 路由: energy/manaProjConfList
 * 方法: POST
 *********************************************************************/
type ManaProjConfList struct {
	mod.SortFinder
	mod.PageFinder

	UId   int64  `form:"uId" json:"uId"  binding:"omitempty"`     //用户ID
	SType int64  `form:"sType" json:"sType"  binding:"omitempty"` //用户角色类型：1 营销，2 推广，3 教学，4 财务，5 技术，6 人事，7 行政，8 高管
	PId   int64  `form:"pId" json:"pId" binding:"omitempty"`      //项目id
	FraId string `form:"fraId" json:"fraId" binding:"omitempty"`  //可操作组织架构ID

}

// 说明：职能配置列表 出参
type ManaProConfigRes struct {
	Id    int64         `form:"id" json:"id"`         //自增ID
	CId   int64         `form:"cId" json:"cId"`       //公司id
	UId   int64         `form:"uId" json:"uId"`       //用户ID
	SType int64         `form:"sType" json:"sType"`   //用户角色类型：1 营销，2 推广，3 教学，4 财务，5 技术，6 人事，7 行政，8 高管
	At    int64         `form:"at" json:"at"`         //插入时间
	CUid  int64         `form:"cUid" json:"cUid"`     //操作人
	PList []ProJListRes `form:"fPList" json:"fPList"` //项目列表

	UName string `form:"uName" json:"uName"` //用户名称

}
type ProJListRes struct {
	Id    int64  `form:"id" json:"id"`       //自增ID
	PId   int64  `form:"pId" json:"pId"`     //项目id
	FId   int64  `form:"fId" json:"fId"`     //关联ID
	FraId uint64 `form:"fraId" json:"fraId"` //框架Id

	PName    string `form:"pName" json:"pName"`       //项目名称
	FraIdStr string `form:"fraIdStr" json:"fraIdstr"` //框架Id string
	FraName  string `form:"fraName" json:"fraName"`   //框架名称
}

func (this *ManaProjConfList) Handle(c *gin.Context, ctx context.Context) htp.Response {
	jwtUser := mod.CurrUser(c)
	fraId, _ := strconv.Atoi(this.FraId)

	//传参
	compyListreq := &gpb.ManaProWheConfReq{
		ManagerInfo: &gpb.ManagerInfo{
			ManagProConfig: &gpb.ManagProConfig{
				CId:   jwtUser.CId,
				UId:   this.UId,
				SType: this.SType,
			},
			ManagPidInfo: &gpb.ManagPidInfo{
				PId:   this.PId,
				FraId: uint64(fraId),
			},
		},
		Page:    int64(this.Page),
		Count:   int64(this.Pnum),
		DesClum: int64(this.Order),
		IsDes:   int64(this.Orule + 1),
	}
	list, err := crm_base.ManaProjConf.GetManaProWheParamList(ctx, compyListreq)
	if list == nil || nil != err {
		return htp.RespParamErr("", err)
	}

	//映射
	items := []*ManaProConfigRes{}
	if err := util.Convert(&items, list.ManaConf); err != nil {
		return htp.RespConvertErr("", err)
	}
	//  设置参数
	this.SetParamList(c, ctx, items)
	if err != nil {
		return htp.RespModelErr("", err)
	}

	return htp.RespOK("", &struct {
		Total int64       `json:"total"`
		List  interface{} `json:"list"`
	}{list.Count, items})

}

/*
* 描述:  职能配置信息添加
* 路由: /energy/addManaProjConf
* 方法: POST
*********************************************************************/
type AddManaProjConf struct {
	PId   int64  `form:"pId" json:"pId" `                    //  项目id
	FId   int64  `form:"fId" json:"fId"  binding:"required"` //  base_con 关联ID
	FraId string `form:"fraId" json:"fraId"`                 //  可操作组织架构ID
}

func (this *AddManaProjConf) Handle(c *gin.Context, ctx context.Context) htp.Response {
	if this.FraId == "" {
		this.FraId = "0"
	}
	fraId, _ := strconv.Atoi(this.FraId)
	req := &gpb.ManagPidInfo{
		PId:   this.PId,
		FId:   this.FId,
		FraId: uint64(fraId),
	}
	_, err := crm_base.ManaProjConf.EditManaProParam(ctx, req)
	if err != nil {
		return htp.RespModelErr("", err)
	}
	return htp.RespOK("", "")
}

/*
* 描述:  职能配置信息添加
* 路由: /energy/addManaProjConf
* 方法: POST
*********************************************************************/
type AddManaPersonConf struct {
	UId   int64 `form:"uId"   json:"uId" json:"required"`              //用户ID
	SType int64 `form:"sType" json:"sType" binding:"required,max=100"` //用户角色类型：1 营销，2 推广，3 教学，4 财务，5 技术，6 人事，7 行政，8 高管
}

func (this *AddManaPersonConf) Handle(c *gin.Context, ctx context.Context) htp.Response {

	jwtUser := mod.CurrUser(c)

	checkUidList := make([]int64, 0)
	checkUidList = append(checkUidList, this.UId)
	checkList, err := crm_base.ManaProjConf.GetUserManaInfo(ctx, &gpb.UserIdsReq{
		UId: checkUidList,
	})
	if err != nil {
		return htp.RespModelErr("", err)
	}
	if checkList != nil && len(checkList.ManaConf) > 0 {
		return htp.RespParamErr("该用户已添加过了", err)
	}

	_, err = crm_base.ManaProjConf.AddManaProParam(ctx, &gpb.ManagProConfig{
		CId:   jwtUser.CId,
		UId:   this.UId,
		SType: this.SType,
		CUid:  jwtUser.UId,
	})
	if err != nil {
		return htp.RespModelErr("", err)
	}
	return htp.RespOK("", "")
}

/*
* 描述: 职能配置信息删除
* 路由: /crm/energy/delcFraProjConf
* 方法: POST
*********************************************************************/
type DelcManaProjConf struct {
	Id int64 `form:"id" json:"id"  binding:"required"` //id
}

func (this *DelcManaProjConf) Handle(c *gin.Context, ctx context.Context) htp.Response {
	req := &gpb.ManagPidInfo{
		Id: this.Id,
	}
	_, err := crm_base.ManaProjConf.DelectManaProParam(ctx, req)
	if err != nil {
		return htp.RespModelErr("", err)
	}
	return htp.RespOK("", "")
}

type ImportManaProjConf struct {
}

type AddImportManaRes struct {
}

//描述: 新增职能项目配置
type AddItem struct {
	Name       string `form:"name" json:"name" binding:"required,max=50"`         // 课次名称
	RoleId     string `form:"video" json:"video"  binding:"omitempty,max=128"`    // 视频Id
	Duration   int32  `form:"duration" json:"duration" binding:"omitempty"`       // 时长(s)
	Instructor string `form:"instructior" json:"instructior" binding:"omitempty"` // 讲师名字
	Audition   int32  `form:"audition" json:"audition" binding:"required"`        // 试听类型(1-非试听, 2-试听)
}

// => 菜单种类
type RoleKind struct {
	Kind int32  `json:"kind"`
	Name string `json:"name"`
}

var RoleKinds = []RoleKind{{1, "营销招生"}, {2, "营销班主任"}, {3, "教学"}, {4, "其他"}}

func (this *ImportManaProjConf) Handle(c *gin.Context, ctx context.Context) htp.Response {

	jwtUser := mod.CurrUser(c)
	cId := jwtUser.CId
	uId := jwtUser.UId
	nowUnix := time.Now().Unix()
	file, _, err := c.Request.FormFile("file")

	xFile, err := excelize.OpenReader(file)
	if err != nil {
		return htp.RespModelErr("文件读取失败", err)
	}

	rows, err := xFile.GetRows("Sheet1")
	if err != nil {
		return htp.RespModelErr("文件读取行信息错误", err)
	}
	//  数据处理
	workIdList := make([]int64, 0)
	for n, row := range rows {
		if n < 1 { // 从第三行开始(排除表头和注释)
			continue
		}
		workid, _ := strconv.ParseInt(row[0], 10, 64)
		if workid > 0 {
			workIdList = append(workIdList, workid)
		}
	}

	userInfo, err := mCache.UserCacheServer.GetLoginsByWorkId(ctx, &gpa.WorkIds{
		WorkId: workIdList,
	})

	names, _ := crm_base.Proj.GetProjNameNames(ctx, cId)

	for rowNum, row := range rows {
		if rowNum < 1 { // 从第三行开始(排除表头和注释)
			continue
		}

		if row[0] == "" || (row[1] == "" && row[2] == "") { // 工号没填，项目没填 则认为结束
			return htp.RespErr(1, "文件解析失败,发生在行:"+fmt.Sprintf("%d", rowNum), nil)
			break
		}
		info := &gpa.LoginNameInfo{}
		hasInfo := true
		for _, user := range userInfo.NameList {
			workid, _ := strconv.ParseInt(row[0], 10, 64)
			if workid == user.WorkId {
				info = user
				hasInfo = false
			}
		}
		if hasInfo {
			return htp.RespErr(1, "文件用户不存在,发生在行:"+fmt.Sprintf("%d", rowNum), nil)
		}

		userId := info.Id              //  用户id
		roleId := info.Role            //  角色id
		pIdList := make([]int64, 0)    //  项目id
		fraIdList := make([]uint64, 0) //  项目id

		if row[1] != "" {
			arr := strings.Split(row[1], ",")
			for _, str := range arr {
				trim := strings.Trim(str, "")
				if trim != "" {
					i := names[trim]
					if i == 0 {
						continue
					}
					pIdList = append(pIdList, i)

				}

			}
		}

		//  组织架构
		if len(row) == 3 {
			arr := strings.Split(row[2], ",")
			for _, str := range arr {
				trim := strings.Trim(str, "")
				if trim != "" {
					nfraId, _ := strconv.Atoi(trim)
					fraIdList = append(fraIdList, uint64(nfraId))
				}

			}
		}

		if len(pIdList) == 0 && len(fraIdList) == 0 {
			return htp.RespErr(1, "没有任何有效的项目或组织架构,发生在行:"+fmt.Sprintf("%d", rowNum), nil)
		}

		//  插入主表 和子表的数据
		response, done := InsertData(ctx, cId, userId, roleId, nowUnix, uId, rowNum, pIdList, fraIdList)
		if done {
			return response
		}
	}
	return htp.RespOK("", "")
}

//**********************************************method*************************************************************

//	设置参数
func (this *ManaProjConfList) SetParamList(c *gin.Context, ctx context.Context, res []*ManaProConfigRes) {
	jwtUser := mod.CurrUser(c)
	cId := jwtUser.CId
	ids := make([]int64, 0)
	for _, resf := range res {
		ids = append(ids, resf.Id)
	}
	//  获取子表数据并填充项目id
	clist := getPList(ids, ctx, cId)

	//  设置员工的名字
	this.setUserList(res, ctx, jwtUser.CId)

	//  设置子表的数据
	for i, _ := range res {
		resf := res[i]
		resf.PList = make([]ProJListRes, 0)
		//  设置子表的数据
		for j, _ := range clist {
			cresf := clist[j]
			if resf.Id == cresf.FId {
				resf.PList = append(resf.PList, cresf)
			}
		}

		ids = append(ids, resf.Id)
	}

}

func (this *ManaProjConfList) setUserList(res []*ManaProConfigRes, ctx context.Context, CId int64) {
	//  获取去重的值
	uidList := this.GetUidList(res)
	userListRes, _ := mCache.UserCacheServer.UserNameList(ctx, &gpa.UserLoginReqIdsReq{CId: CId, Ids: uidList})

	for i, _ := range res {
		resf := res[i]
		resf.PList = make([]ProJListRes, 0)
		//组织架构赋值
		if userListRes != nil && len(userListRes.NameList) > 0 {

			for _, vf := range userListRes.NameList {
				if resf.UId == vf.Id && vf.Name != "" {
					resf.UName = vf.Name
				}
			}
		}

	}
}

//  获取去重的值Uid
func (this *ManaProjConfList) GetUidList(res []*ManaProConfigRes) (uidList []int64) {
	for _, v := range res {
		fage := false
		for ssi, _ := range uidList {
			if v.UId == uidList[ssi] {
				fage = true
				break
			}
		}
		if !fage {
			uidList = append(uidList, v.UId)
		}
	}
	return
}

//  获取子表数据
func getPList(ids []int64, ctx context.Context, cId int64) (items []ProJListRes) {

	craParamsReq := &gpb.ManaReqIds{
		Ids: ids,
	}
	clist, err := crm_base.ManaProjConf.GetJoinInfo(ctx, craParamsReq)
	if err != nil || clist.ManagPidInfo == nil || len(clist.ManagPidInfo) == 0 {
		return
	}
	if err := util.Convert(&items, clist.ManagPidInfo); err != nil {
		return
	}
	names, err := crm_base.Proj.GetProjIdNames(ctx, cId)

	s_showids := GetShowIdFraIdList(items)

	frawCacheres, _ := mCache.FrameWorkCache.GetFraNameByShowIdList(ctx, &gpa.FullReqUIdsReq{
		Ids: s_showids,
	})

	for i, _ := range items {
		it := &items[i]
		if it.FraId > 0 {
			it.FraIdStr = fmt.Sprintf("%d", it.FraId)
		}
		it.PName = names[it.PId]

		//组织架构赋值
		if frawCacheres != nil && len(frawCacheres.FullUList) > 0 {

			for _, vf := range frawCacheres.FullUList {
				if it.FraId == vf.Id && vf.Name != "" {
					it.FraName = vf.FullName
				}

			}
		}

	}
	return
}

//  插入主表 和子表的数据
func InsertData(ctx context.Context, cId int64, userId int64, roleId int64, nowUnix int64, uId int64, rowNum int, pIdList []int64, fraIdList []uint64) (htp.Response, bool) {

	checkUidList := make([]int64, 0)
	checkUidList = append(checkUidList, userId)
	checkList, err := crm_base.ManaProjConf.GetUserManaInfo(ctx, &gpb.UserIdsReq{
		UId: checkUidList,
	})

	config := &gpb.ManagProConfig{
		CId:   cId,
		UId:   userId,
		SType: roleId,
		At:    nowUnix,
		CUid:  uId,
	}
	fId := int64(0)
	if checkList == nil || len(checkList.ManaConf) == 0 {
		mainInfo, err := crm_base.ManaProjConf.AddManaProParam(ctx, config)
		fmt.Sprintln(err)
		fId = int64(mainInfo.Id)
	} else {
		fId = checkList.ManaConf[0].Id
	}

	if err != nil {
		return htp.RespErr(1, "文件插入名称失败,发生在行:"+fmt.Sprintf("%d", rowNum), nil), true
	}
	// 子表插入数据
	if len(pIdList) > 0 {

		for _, v := range pIdList {
			fmt.Sprintf("===========================,pid :%d fid :%d", v, fId)

			res, err := crm_base.ManaProjConf.EditManaProParam(ctx, &gpb.ManagPidInfo{
				PId: v,
				FId: fId,
			})
			if err != nil {
				fmt.Sprintln(err)
				fmt.Sprintln(res)
			}

		}
	} else if len(fraIdList) > 0 {
		for _, v := range fraIdList {
			fmt.Sprintf("===========================,框架id :%s fid :%d", v, fId)
			res, err := crm_base.ManaProjConf.EditManaProParam(ctx, &gpb.ManagPidInfo{
				FraId: v,
				FId:   fId,
			})
			if err != nil {
				fmt.Sprintln(err)
				fmt.Sprintln(res)
			}

		}
	}
	return htp.Response{}, false
}
func GetShowIdFraIdList(res []ProJListRes) (s_showids []uint64) {
	for _, v := range res {
		fage := false
		for ssi, _ := range s_showids {
			if v.FraId == s_showids[ssi] {
				fage = true
				break
			}
		}
		if !fage {
			s_showids = append(s_showids, v.FraId)
		}
	}
	return
}
